from flask import request
from flask.ext.classy import FlaskView, route
from peewee import *
from peewee import fn
from . import jsonify_with_error

quotes = [
    "A noble spirit embiggens the smallest man! ~ Jebediah Springfield",
    "If there is a way to do it better... find it. ~ Thomas Edison",
    "No one knows what he can do till he tries. ~ Publilius Syrus"
]

from ..models.product import Product
from ..models.currency import Currency
from ..models.offer import Offer
from ..schema.object import ProductSchema, fetch_hot_product_params, success_schema, currency_schema, hot_product_schema
from . import jsonify_with_success
from ..schema.param import hot_product_param, product_query_param
from ..schema.error import CURRENCY_NOT_EXIST, PRODUCT_NOT_EXIST
from ..schema.resp import product_with_price_list_resp, currency_resp, success_resp,more_product


# def jsonify_with_success(result, total=None):
#     api_status = None
#     if request.method == 'POST':
#         api_status = 201
#     else:
#         api_status = 200
#     resp = {'success': True, 'message': 'api_status', 'result': result}
#     if total:
#         resp.update(
#             {'total': total}
#         )
#     print(resp)
#     return jsonify(resp), api_status


class ProductsView(FlaskView):
    def before_request(self, name, **args):
        import datetime
        print("something is happening to a widget", datetime.datetime.now())

    def after_request(self, name, response):
        print("something happened to a widget")
        return response

    def index(self):
        from ..models.product import Metadata
        from ..models.product import ProductMetadata

        product_list = Product.get_list()

        # metadata = ProductMetadata.select()
        #
        # ProductMetadata.select()
        # product_with_metadata_desc  = prefetch(ProductMetadata.select(),Metadata.select())
        #
        # for p in product_with_metadata_desc:
        #     print(p)
        #     pass
        # # metadata = ProductMetadata.select(ProductMetadata, Metadata).join(Metadata)
        # metadata_desc = Metadata.select()
        # product_with_metadata = prefetch(product, metadata)
        #
        # for i in product_with_metadata:
        #     for q in i.metadata:
        #         pass
        #         # print(q.metadata)
        return jsonify_with_success(ProductSchema().dump(product_list, many=True).data)

    @route('/filter_list', methods=['POST', 'GET'])
    def filter_list(self):
        param = {}
        if request.data:
            param, _ = product_query_param.loads(request.data.decode(request.charset or 'utf8'))

        if 'currency' in param:
            currency = Currency.get_or_none(Currency.id == param.get('currency'))
            if not currency:
                return jsonify_with_error(**CURRENCY_NOT_EXIST.to_map())
        else:
            currency = Currency.get_main_currency()

        max_size = param.get('max_size', 10)

        conditions = []
        if 'last_id' in param:
            product = Product.get_or_none(Product.id == param['last_id'])
            if product:
                conditions.append(Product.collection_count < product.collection_count)

        if 'title' in param:
            conditions.append(Product.title % ('%' + param['title'] + '%'))

        product_with_stock = list(Product.get_list_with_stock(*conditions,
                                                              order_by=Product.collection_count.desc(),
                                                              limit=max_size))

        for p in product_with_stock:
            stock = p.stock
            stock.sort(key=lambda x: x.price)
            if stock:
                p.min_price = round(stock[0].price * currency.rate, 2)
                p.max_price = round(stock[-1].price * currency.rate, 2)
            else:
                p.min_price = 0.00
                p.max_price = 0.00

        total = Product.get_list_count(*conditions)

        last_id = None if len(product_with_stock) <= 0 else product_with_stock[-1].id
        return more_product.jsonify({
            'currency': currency_resp.dump(currency).data,
            'items': product_with_price_list_resp.dump(product_with_stock).data,
            'last_id': last_id,
            'remaining': 0 if total - max_size <= 0 else total - max_size
        })


    @route('/hot_list', methods=['POST', 'GET'])
    def fetch_host_list(self):

        if request.data:
            params, errors = hot_product_param.loads(
                request.data.decode(request.charset or 'utf8'))
        else:
            params, errors = ({}, {})
        if errors:
            pass
        currency = params.get('currency', None)
        category = params.get('category', None)
        limit = params.get('max_count', 10)
        if not currency:
            currency = Currency.get_main_currency()

        where = []
        if category:
            where.append(Product.category == category)

        product_with_stock = list(Product.get_list_with_stock(*where
                                                              , limit=limit))

        for p in product_with_stock:
            stock = p.stock
            if stock:
                stock.sort(key=lambda x: x.price)

                p.min_price = stock[0].price * currency.rate
                p.max_price = stock[-1].price * currency.rate
            else:
                p.min_price = 0.00
                p.max_price = 0.00

        return success_schema.jsonify({
            'currency': currency_schema.dump(currency).data,
            'list': hot_product_schema.dump(product_with_stock).data
        })

    @route('/title/<title>')
    def find_by_title(self, title):
        product = Product.get_or_none(Product.title == title)
        # language = request.values['l']
        language = request.args.get('l', None)
        currency = request.args.get('c', None)

        if not currency:
            currency = Currency.get_main_currency()
        else:
            currency = Currency.get_or_none(Currency.id == currency)

        schema = ProductSchema()
        if product:
            stat = Offer.stat_price(product, currency)
            if stat:
                product.offer = stat
            schema.context = {
                'currency': currency,
                'language': language
            }
        else:
            return PRODUCT_NOT_EXIST.jsonify()
        return jsonify_with_success(schema.dump(product).data)
